/**
 * 存储模块 - 提供localStorage和sessionStorage的增强功能
 */

/**
 * 检查存储是否可用
 * @param {string} type 存储类型 ('localStorage' | 'sessionStorage')
 * @returns {boolean} 是否可用
 */
function isStorageAvailable(type) {
  try {
    const storage = window[type];
    const x = '__storage_test__';
    storage.setItem(x, x);
    storage.removeItem(x);
    return true;
  } catch (e) {
    return false;
  }
}

/**
 * 安全的存储操作类
 */
class SafeStorage {
  constructor(storageType) {
    this.storage = isStorageAvailable(storageType) ? window[storageType] : null;
    this.fallback = new Map();
  }

  /**
   * 设置存储项
   * @param {string} key 键
   * @param {any} value 值
   * @param {number} expires 过期时间（毫秒）
   * @returns {boolean} 是否成功
   */
  setItem(key, value, expires) {
    try {
      const item = {
        value,
        timestamp: Date.now(),
        expires: expires ? Date.now() + expires : null
      };

      const serialized = JSON.stringify(item);

      if (this.storage) {
        this.storage.setItem(key, serialized);
      } else {
        this.fallback.set(key, serialized);
      }
      return true;
    } catch (e) {
      return false;
    }
  }

  /**
   * 获取存储项
   * @param {string} key 键
   * @param {any} defaultValue 默认值
   * @returns {any} 值
   */
  getItem(key, defaultValue = null) {
    try {
      let serialized;

      if (this.storage) {
        serialized = this.storage.getItem(key);
      } else {
        serialized = this.fallback.get(key);
      }

      if (!serialized) return defaultValue;

      const item = JSON.parse(serialized);

      // 检查是否过期
      if (item.expires && Date.now() > item.expires) {
        this.removeItem(key);
        return defaultValue;
      }

      return item.value;
    } catch (e) {
      return defaultValue;
    }
  }

  /**
   * 移除存储项
   * @param {string} key 键
   * @returns {boolean} 是否成功
   */
  removeItem(key) {
    try {
      if (this.storage) {
        this.storage.removeItem(key);
      } else {
        this.fallback.delete(key);
      }
      return true;
    } catch (e) {
      return false;
    }
  }

  /**
   * 清空存储
   * @returns {boolean} 是否成功
   */
  clear() {
    try {
      if (this.storage) {
        this.storage.clear();
      } else {
        this.fallback.clear();
      }
      return true;
    } catch (e) {
      return false;
    }
  }

  /**
   * 获取存储大小
   * @returns {number} 存储大小（字节）
   */
  getSize() {
    let size = 0;
    try {
      if (this.storage) {
        for (const key in this.storage) {
          if (Object.prototype.hasOwnProperty.call(this.storage, key)) {
            size += this.storage[key].length + key.length;
          }
        }
      } else {
        for (const [key, value] of this.fallback) {
          size += value.length + key.length;
        }
      }
    } catch (e) {
      // ignore
    }
    return size;
  }

  /**
   * 获取所有键
   * @returns {string[]} 键数组
   */
  getKeys() {
    const keys = [];
    try {
      if (this.storage) {
        for (let i = 0; i < this.storage.length; i++) {
          keys.push(this.storage.key(i));
        }
      } else {
        for (const key of this.fallback.keys()) {
          keys.push(key);
        }
      }
    } catch (e) {
      // ignore
    }
    return keys;
  }

  /**
   * 检查键是否存在
   * @param {string} key 键
   * @returns {boolean} 是否存在
   */
  hasKey(key) {
    try {
      if (this.storage) {
        return this.storage.getItem(key) !== null;
      } else {
        return this.fallback.has(key);
      }
    } catch (e) {
      return false;
    }
  }

  /**
   * 清理过期项
   * @returns {number} 清理的项目数量
   */
  clearExpired() {
    let count = 0;
    const keys = this.getKeys();

    keys.forEach(key => {
      try {
        let serialized;
        if (this.storage) {
          serialized = this.storage.getItem(key);
        } else {
          serialized = this.fallback.get(key);
        }

        if (serialized) {
          const item = JSON.parse(serialized);
          if (item.expires && Date.now() > item.expires) {
            this.removeItem(key);
            count++;
          }
        }
      } catch (e) {
        // ignore invalid items
      }
    });

    return count;
  }
}

// 创建实例
const localStorage = new SafeStorage('localStorage');
const sessionStorage = new SafeStorage('sessionStorage');

// LocalStorage 相关函数
export function setLocal(key, value, expires) {
  return localStorage.setItem(key, value, expires);
}

export function getLocal(key, defaultValue) {
  return localStorage.getItem(key, defaultValue);
}

export function removeLocal(key) {
  return localStorage.removeItem(key);
}

export function clearLocal() {
  return localStorage.clear();
}

export function getLocalSize() {
  return localStorage.getSize();
}

export function getLocalKeys() {
  return localStorage.getKeys();
}

export function hasLocalKey(key) {
  return localStorage.hasKey(key);
}

export function clearLocalExpired() {
  return localStorage.clearExpired();
}

// SessionStorage 相关函数
export function setSession(key, value, expires) {
  return sessionStorage.setItem(key, value, expires);
}

export function getSession(key, defaultValue) {
  return sessionStorage.getItem(key, defaultValue);
}

export function removeSession(key) {
  return sessionStorage.removeItem(key);
}

export function clearSession() {
  return sessionStorage.clear();
}

export function getSessionSize() {
  return sessionStorage.getSize();
}

export function getSessionKeys() {
  return sessionStorage.getKeys();
}

export function hasSessionKey(key) {
  return sessionStorage.hasKey(key);
}

export function clearSessionExpired() {
  return sessionStorage.clearExpired();
}

/**
 * Cookie 操作函数
 */
export const cookie = {
  /**
   * 设置Cookie
   * @param {string} name Cookie名称
   * @param {string} value Cookie值
   * @param {Object} options 选项
   */
  set(name, value, options = {}) {
    let cookieString = `${encodeURIComponent(name)}=${encodeURIComponent(value)}`;

    if (options.expires) {
      if (typeof options.expires === 'number') {
        const expires = new Date(Date.now() + options.expires * 1000);
        cookieString += `; expires=${expires.toUTCString()}`;
      } else if (options.expires instanceof Date) {
        cookieString += `; expires=${options.expires.toUTCString()}`;
      }
    }

    if (options.path) {
      cookieString += `; path=${options.path}`;
    }

    if (options.domain) {
      cookieString += `; domain=${options.domain}`;
    }

    if (options.secure) {
      cookieString += '; secure';
    }

    if (options.sameSite) {
      cookieString += `; samesite=${options.sameSite}`;
    }

    document.cookie = cookieString;
  },

  /**
   * 获取Cookie
   * @param {string} name Cookie名称
   * @param {string} defaultValue 默认值
   * @returns {string|null} Cookie值
   */
  get(name, defaultValue = null) {
    const nameEQ = encodeURIComponent(name) + '=';
    const cookies = document.cookie.split(';');

    for (const cookie of cookies) {
      const c = cookie.trim();
      if (c.indexOf(nameEQ) === 0) {
        return decodeURIComponent(c.substring(nameEQ.length));
      }
    }

    return defaultValue;
  },

  /**
   * 删除Cookie
   * @param {string} name Cookie名称
   * @param {Object} options 选项
   */
  remove(name, options = {}) {
    this.set(name, '', {
      ...options,
      expires: -1
    });
  },

  /**
   * 获取所有Cookie
   * @returns {Object} Cookie对象
   */
  getAll() {
    const cookies = {};
    const cookieArray = document.cookie.split(';');

    for (const cookie of cookieArray) {
      const [name, value] = cookie.trim().split('=');
      if (name && value) {
        cookies[decodeURIComponent(name)] = decodeURIComponent(value);
      }
    }

    return cookies;
  },

  /**
   * 清空所有Cookie
   */
  clear() {
    const cookies = this.getAll();
    for (const name in cookies) {
      this.remove(name);
    }
  }
};

/**
 * 通用存储接口
 */
export const storage = {
  /**
   * 设置存储项（自动选择最佳存储方式）
   * @param {string} key 键
   * @param {any} value 值
   * @param {Object} options 选项
   */
  set(key, value, options = {}) {
    const { type = 'local', expires } = options;

    switch (type) {
      case 'session':
        return setSession(key, value, expires);
      case 'cookie':
        return cookie.set(key, JSON.stringify(value), options);
      case 'local':
      default:
        return setLocal(key, value, expires);
    }
  },

  /**
   * 获取存储项
   * @param {string} key 键
   * @param {any} defaultValue 默认值
   * @param {string} type 存储类型
   * @returns {any} 值
   */
  get(key, defaultValue = null, type = 'local') {
    switch (type) {
      case 'session':
        return getSession(key, defaultValue);
      case 'cookie':
        try {
          const value = cookie.get(key);
          return value ? JSON.parse(value) : defaultValue;
        } catch (e) {
          return defaultValue;
        }
      case 'local':
      default:
        return getLocal(key, defaultValue);
    }
  },

  /**
   * 移除存储项
   * @param {string} key 键
   * @param {string} type 存储类型
   */
  remove(key, type = 'local') {
    switch (type) {
      case 'session':
        return removeSession(key);
      case 'cookie':
        return cookie.remove(key);
      case 'local':
      default:
        return removeLocal(key);
    }
  }
};
